package com.keba.otp.server.mobilecontrol;

import java.io.IOException;

import java.io.OutputStream;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.catalina.util.DateTool;
import org.bouncycastle.util.encoders.Hex;


import com.keba.otp.core.Tempkey;
import com.keba.otp.core.User;
import com.keba.otp.crypto.Crypto;
import com.keba.otp.db.DAOFactory;
import com.keba.otp.db.TempkeysDAO;
import com.keba.otp.db.UsersDAO;
import com.keba.otp.server.otpgen.OTP;
import com.sun.xml.internal.ws.transport.http.HttpAdapter;

/**
 * A klienssel valo kommunikaciot biztosito Servlet
 * @author bejmuller
 *
 */
public class MobileControlMain extends HttpServlet implements MobileInterface {
	private static final long serialVersionUID = 1L;

	/**
	 * @see HttpServlet#HttpServlet()
	 */
	public MobileControlMain() {
		super();
	}

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
	}
	
	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		String action = request.getParameter("action");
		if (action != null) {
			if (action.equals("login")) {
				login(request.getParameter("user"), request.getParameter("passw"), response);
			} else if (action.equals("register")) {
				register(request.getParameter("user"), request.getParameter("passw"), request.getParameter("tempkey"), response);
			} else if (action.equals("generate")) {
				generate(request.getParameter("sessionkey"), response);
			}
		}
	}
	
	/**
	 * A bejelentkezest vegzi el, adatbazisba lement egy uj session key-t, es ezt elkuldi a kliensnek
	 * @param user felhasznalonev
	 * @param passw jelszo
	 * @response a Servlet valasza a requestre
	 */
	@Override
	public void login(String user, String passw, HttpServletResponse response) {
		response.setContentType("application/octet-stream");
		DAOFactory daofactory = DAOFactory.getInstance(DAOFactory.MYSQL);
		UsersDAO usersdao = daofactory.getUsersDAO();
		User foundUser;
		if ((foundUser = usersdao.getUserByName(user)) != null) {
			if (foundUser.getPassw().equals(passw)) {
				/*
				 * megvan az adatbazisban a user, es egyezik a jelszo
				 * uzenet: generalt sessionKey
				 */
				OutputStream os;
				try {
					String sessionKey = generateNewSessionKey();
					foundUser.setSessionKey(sessionKey);
					usersdao.updateSessionKey(foundUser);
					os = response.getOutputStream();
					os.write(Crypto.performEncrypt(sessionKey, foundUser.getKey()).getBytes());
					os.flush();
					os.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			} else {
				/*
				 * megvan a user, de nem egyezik a jelszo, hibauzenet -1
				 */
				OutputStream os;
				try {
					os = response.getOutputStream();
					os.write(-1);
					os.flush();
					os.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		} else {
			/*
			 * nincs meg a user, hibauzenet -2
			 */
			OutputStream os;
			try {
				os = response.getOutputStream();
				os.write(-2);
				os.flush();
				os.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	/**
	 * A regisztraciot vegzi el, adatbazisba lementi a kovetkezoket:
	 * -egy uj kriplashoz szukseges key-t
	 * -ennek a kulcsnak a segitsegevel a felhasznalonevet es a jelszot kriptalva
	 * A key-t elkuldi a kliensnek
	 * @param user felhasznalonev
	 * @param passw jelszo
	 * @response a Servlet valasza a requestre
	 */
	@Override
	public void register(String user, String passw, String tempKey, HttpServletResponse response) {
		DAOFactory daofactory = DAOFactory.getInstance(DAOFactory.MYSQL);
		UsersDAO usersdao = daofactory.getUsersDAO();
		TempkeysDAO tempkeysdao = daofactory.getTempkeysDAO();
		response.setContentType("application/octet-stream");
		try {
			Tempkey tempkey;
			byte[] key;
			if ((tempkey = tempkeysdao.getKeyById(tempKey)) != null)
			{
				if ((key = tempkey.getKey()) != null){
					String encryptedUser = Crypto.performEncrypt(user,key);
					String encryptedPassw = Crypto.performEncrypt(passw,key);
					User foundUser;
					if ((foundUser = usersdao.getUserByName(encryptedUser)) != null 
						&& foundUser.getPassw().equals(encryptedPassw)) {
						//tempkeysdao.removeTempkey(tempkey);
						OutputStream os = response.getOutputStream();
						os.write(key);
						os.flush();
						os.close();
				}
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * Az OTP generalasat vegzi, amit elkuld a kliensnek
	 * @param sessionKey a user bejelentkezeset megerosito session key
	 * @response a Servlet valasza a requestre
	 */
	@Override
	public void generate(String sessionKey, HttpServletResponse response) {
		DAOFactory daofactory = DAOFactory.getInstance(DAOFactory.MYSQL);
		UsersDAO usersdao = daofactory.getUsersDAO();
		response.setContentType("application/octet-stream");
			try {
				OutputStream os = response.getOutputStream();
				String otp = OTP.generateOTP();
				User temp = usersdao.getUserBySessionKey(sessionKey);
				SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.S");
				Date lastAccess = sdf.parse(temp.getLastAccessDate());
				Date now = new Date();
				if (now.getTime() - lastAccess.getTime() < 90000) {
					if (temp != null) {
						temp.setOtp(otp);
						usersdao.updateOTP(temp);
						usersdao.updateSessionKey(temp);
						os.write(Crypto.performEncrypt(otp, temp.getKey()).getBytes());
						os.flush();
						os.close();
					}
				}
			} catch (IOException e) {
				e.printStackTrace();
			} catch (ParseException e) {
				e.printStackTrace();
			}
	}
	
	/**
	 * uj session key-t general
	 * @return a generalt session key
	 */
	@Override
	public String generateNewSessionKey() {
		return org.apache.commons.lang.RandomStringUtils.randomAlphanumeric(16);
	}


}
